<?php
/** 
 * 
 *
 * @package api
 * @subpackage db
 * @author Richard Fullmer <php-api@byu.edu>
 * 
 * @version 1.0
 */
/**
 *
 */
require_once( "MDB2.php" );
require_once( "lang/DatabaseException.php" );

 
/**
 * 
 * @package api
 * @subpackage db
 * @author Richard Fullmer <php-api@byu.edu>
 * 
 * @version 1.0
 */
abstract class Mapper {
	static $db;
	static $dsn;
		
	public function __construct( $dsn ) {
		if (! self::$db ) {
			if ( !$dsn )
				throw new DatabaseException();
			
			self::$dsn = $dsn;
			self::$db = MDB2::factory( self::$dsn );
			
			if (MDB2::isError( self::$db ) ) {
				throw new DatabaseException( self::$db->getUserInfo() );
			}
		}
	}
	
	public function __destruct() { }
	
	protected function load($result) {
		$array = $result->fetchRow( MDB2_FETCHMODE_ASSOC );
		
		if (!is_array($array)) return null;
		if (!$array['id']) return null;

		return $this->loadArray($array);
	}
	
	public function loadArray($array) {
		$obj = $this->doLoad($array);
		$obj->markClean();
		return $obj;
	}
	
	protected function prepareStatement( $sql ) {
		$statement = self::$db->prepare( $sql );
		if ( !$this->checkError( $statement ) )
			throw new AppException("Initial prepared mappers statements invalid<BR> <pre>$sql</pre>");
			
		return $statement;
	}
		
	public function doSql( $sql ) {
		$db_result = self::$db->query( $sql );
		
		if ( !$this->checkError( $db_result ) )
			return false;
		
		return $db_result;
	}
	
	public function doStatement($statement, $values) {	
		if ( !$this->checkError( $statement ) )
			return false;
			
		$db_result = $statement->execute($values);
		
		if ( !$this->checkError( $db_result ) )
			return false;
		
		return $db_result;
	}
	
	private function checkError( $db_result ) {
		if (MDB2::isError( $db_result )) {
			$description  = 'Standard Message: ' . $db_result->getMessage() . "<BR>";
			$description .= 'Standard Code: ' . $db_result->getCode() . "<BR>";
			$description .= 'MDB2/User Message: ' . $db_result->getUserInfo() . "<BR>";
			$description .= 'MDB2/Debug Message: ' . $db_result->getDebugInfo() . "<BR>";
			echo $description;
			return false;
		}
		else
			return true;
	}
		
	public function insert( DatabaseObject $obj ) {
        $this->doInsert( $obj );
    }
	
	public function update( DatabaseObject $obj ) {
        $this->doUpdate( $obj );
    }
    
    public function delete( DatabaseObject $obj ) {
    	$this->doDelete( $obj );
    }
	
	public abstract function find($id);
	public abstract function findAll();
	public abstract function findBySql( $sql );
	public abstract function findAllBySql( $sql );

	protected abstract function newId();
	protected abstract function doLoad($array);
		
	protected abstract function doInsert( DatabaseObject $object );
	protected abstract function doUpdate( DatabaseObject $object );
	protected abstract function doDelete( DatabaseObject $object );
	
	protected abstract function targetClass();
	protected abstract function targetCollection();
	
	//protected abstract function getSelectStatement();
	//protected abstract function getSelectAllStatement();
	
	
}

?>